import { Component, Inject, Injector } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Service } from '@api';
import { QueryBody } from '@api/model/queryBody.model';
import { QueryParams } from '@api/model/queryParams.model';
import { SimpleListField } from '@api/simple/model/simpleListField.model';
import { SimpleListFormFields } from '@api/simple/model/simpleListFormFields.model';
import { OptionService } from '@api/simple/service/options.service';
import { SimpleService } from '@api/simple/service/simple.service';
import { SimpleListService } from '@api/simple/service/simpleList.service';
import { _HttpClient, ModalHelper } from '@delon/theme';
import { environment } from '@env/environment';
import { stringTemplate } from '@shared/utils/string';
import { NzMessageService } from 'ng-zorro-antd/message';
import { ListComponent } from 'src/app/routes/common/list/list.component';

import { SimpleEditComponent } from './edit/edit.component';

@Component({
  selector: 'app-simple-dynamic-general-list',
  templateUrl: './general.list.component.html',
  styles: [
    `
      .ant-input.demo-input-right {
        width: 100px;
        text-align: center;
        border-left-width: 0px;
      }

      .ant-input.demo-input-right:hover,
      .ant-input.demo-input-right:focus {
        border-left-width: 1px;
      }

      .ant-input.ant-input-rtl.demo-input-right {
        border-right-width: 0px;
      }
    `,
  ],
})
export class SimpleGeneralcListComponent extends ListComponent<any, string> {
  allChecked = false;
  indeterminate = false;
  setOfCheckedId = new Set<number>();

  code = '';
  simpleListFormFields: SimpleListFormFields = {};
  params: any = {};
  isCollapse = false;

  queryBody: QueryBody<any> = {};
  queryParams: QueryParams<any> = {
    isPage: true,
    pageNumber: 1,
    pageSize: 20,
    listRequired: true,
    totalRequired: false,
    sort: '',
    params: {},
  };

  optionMap: any = {};

  isQueryTotal = true;

  options: any = {};

  checkboxOptions: any = {};

  constructor(
    public http: _HttpClient,
    public modal: ModalHelper,
    public simpleListService: SimpleListService,
    @Inject(SimpleService) public service: Service<any, string>,
    public msgSrv: NzMessageService,
    public router: Router,
    public route: ActivatedRoute,
    public injector: Injector,
    public optionService: OptionService,
  ) {
    super(http, modal, service, msgSrv, SimpleEditComponent);
  }

  ngOnInit() {
    this.code = this.getCode();
    const listParamsFlag = ['between', 'betweenEquals', 'in', 'notIn'];
    this.simpleListService.findSimpleListFormFieldsByCode(this.code).subscribe((res) => {
      this.simpleListFormFields = res;
      this.simpleListFormFields.fields?.forEach((field) => {
        if (field.type == 'keyValue') {
          const option: any = {};
          option[field.pattern!] = {};
          this.options[field.format!] = option;
        }
      });
      this.simpleListFormFields.form?.fields.forEach((field) => {
        let paramInitValue: any = field.value;
        if (listParamsFlag.indexOf(field.operator!) > -1) {
          paramInitValue = [];
          if (field.value) {
            paramInitValue = field.value.split(',');
          }
        }
        this.queryParams.params[field.code!] = paramInitValue;
        if (field.widget == 'select') {
          const option: any = {};
          option[field.pattern!] = [];
          this.options[field.format!] = option;
        }
      });

      for (let type in this.options) {
        for (let param in this.options[type]) {
          this.optionService.findByType(type, param).subscribe((option) => (this.options[type][param] = option));
        }
      }

      if (res.datasourceType == 'URL') {
        this.url = stringTemplate(res.datasourceId!, { environment: environment });
      } else if (res.datasourceType == 'SQL') {
        this.url = `${environment.simple.ctx}/simpleList/data/${this.code}`;
      }
      this.isUILoad = true;
      this.queryData();
    });
  }

  queryData() {
    this.http.post(this.url, this.queryParams).subscribe((res) => {
      this.queryBody = res;
    });
    if (this.isQueryTotal) {
      this.queryParams.totalRequired = true;
      this.http.post(this.url, this.queryParams).subscribe((res) => {
        this.queryBody.totalRow = res.totalRow;
        this.queryBody.totalPage = res.totalPage;
        this.queryParams.totalRequired = false;
        this.isQueryTotal = false;
      });
    }
  }

  getCode() {
    return (this.code = this.route.snapshot.params.code);
  }

  updateCheckedSet(id: number, checked: boolean): void {
    if (checked) {
      this.setOfCheckedId.add(id);
    } else {
      this.setOfCheckedId.delete(id);
    }
  }

  refreshCheckedStatus(): void {
    const listOfEnabledData = this.queryBody.list!;
    this.allChecked = listOfEnabledData.every(({ id }) => this.setOfCheckedId.has(id));
    this.indeterminate = listOfEnabledData.some(({ id }) => this.setOfCheckedId.has(id)) && !this.allChecked;
    this.ifvars.isBatchOperate = this.setOfCheckedId.size > 0;
  }

  onItemChecked(id: number, checked: boolean): void {
    this.updateCheckedSet(id, checked);
    this.refreshCheckedStatus();
  }

  onAllChecked(checked: boolean): void {
    this.queryBody.list!.filter(({ disabled }) => !disabled).forEach(({ id }) => this.updateCheckedSet(id, checked));
    this.refreshCheckedStatus();
  }

  sortOrderChange(simpleListField: SimpleListField) {
    this.simpleListFormFields.fields?.forEach((field) => {
      if (field.code != simpleListField.code) {
        field.sortOrder = null;
      }
    });
    if (simpleListField.sortOrder) {
      this.queryParams.sort = `${simpleListField.code} ${simpleListField.sortOrder}`;
    }
    this.queryData();
  }

  isTrue(expression?: string): boolean {
    if (expression == undefined || expression == null || expression == '') {
      return true;
    }
    const str = stringTemplate(`{{${expression}}}`, this);
    return str == 'true' ? true : false;
  }

  checkboxChange(code: string, value: any, checked: Boolean) {
    const values = this.queryParams.params[code];
    const index = values.indexOf(value);
    if (checked) {
      if (index == -1) {
        values.push(value);
      }
    } else {
      if (index > -1) {
        values.splice(index, 1);
      }
    }
  }

  formValueChange(code: string, value: any) {
    this.isQueryTotal = true;
  }

  getOption(type: string, param: string, value: string): any {
    const option = this.options[type][param].find((o: any) => o.code == value);
    return option;
  }

  getCheckOptions(type: string, param: string): any[] {
    const checkOptions: any[] = [];
    this.options[type][param].forEach((item: any) => {
      if (item.enabled != 'N') {
        checkOptions.push({ label: item.text, value: item.code, checked: false });
      }
    });
    return checkOptions;
  }
}
